package datastructure;

import java.util.InputMismatchException;

/**
 * A command class which helps to interpret the strings sent from the server and
 * encode the strings sent to the server.
 * 
 * @author dt08sj7
 */
public class Command {

	private String ssn;
	private String hash;
	private String type;
	private String data;
	private long timestamp;
	private String nounce;

	/**
	 * 
	 * 
	 * Creates a command of a string. The string must follow the
	 * Johansson-Hallberg protocol.
	 * 
	 * @param text
	 *            The string which the command will be created from.
	 * @throws Exception
	 *             if the string is of an invalid format.
	 */

	public Command(String text) throws Exception {
		parseText(text);
	}

	/**
	 * Inserts the correct values into the command from the string.
	 * 
	 * @param text
	 *            The string with the stored values.
	 * @throws InputMismatchException
	 *             If the values are incorrect.
	 */
	private void parseText(String text) throws InputMismatchException {
		System.out.println(text);
		String[] split = text.split(";");
		System.out.println("längd på hela: " + split.length);
		System.out.println("längd på ssn: " + split[0].length());

		if (text.contains(";:") || text.contains(":;") || text.contains("::")) {
			throw new InputMismatchException();
		}

		if (split.length != 6 || split[0].length() != 11) {
			System.out.println("Gick in i dåligt antal  fält etc...");
			throw new InputMismatchException();
		}

		System.out.println("Antalfält i Data fältet: "
				+ split[3].split(":").length);
		if (split[2] == "read") {

		} else if (split[2].equalsIgnoreCase("append")
				&& (split[3].split(":").length != 6)) {
			System.out.println("Append...");
			throw new InputMismatchException();

		} else if (split[2].equalsIgnoreCase("delete")) {
			checkRecordNumberValidity(split[3]);

		} else if (split[2].equalsIgnoreCase("deleteall")) {
			checkValidSSNFormat(split[3]);

		} else if (split[2].equalsIgnoreCase("readspec")) {
			checkValidSSNFormat(split[3]);
		} else if (split[2].equalsIgnoreCase("nouncereq")) {
			System.out.println("Nouncereq...");
			checkValidSSNFormat(split[0]);
		}

		ssn = split[0];
		hash = split[1];
		type = split[2];
		data = split[3];
		timestamp = Long.parseLong(split[4]);
		nounce = split[5];

	}

	/**
	 * Controls if the recordNumber field contains numbers, and therefore are
	 * valid.
	 * 
	 * @param split
	 *            The recordNumber field.
	 */
	private void checkRecordNumberValidity(String split) {
		try {
			Integer.parseInt(split);
		} catch (NumberFormatException e) {
			throw new InputMismatchException();
		}
	}

	/**
	 * Controls that the SSN field is of a correct format.
	 * 
	 * @param ssnfraction
	 *            The ssn field.
	 */

	private void checkValidSSNFormat(String ssnfraction) {
		try {
			Integer.parseInt((String) ssnfraction.subSequence(0, 5));
			Integer.parseInt((String) ssnfraction.subSequence(7, 10));
		} catch (NumberFormatException e) {
			throw new InputMismatchException();
		}
	}

	/**
	 * Returns the type of the command.
	 * 
	 * @return a string with the type of the command.
	 */
	public String getType() {
		return type;
	}

	/**
	 * Returns the SSN stored in the command.
	 * 
	 * @return a string with the ssn.
	 */
	public String getSsn() {
		return ssn;
	}

	/**
	 * Returns the hash-value stored in the command.
	 * 
	 * @return a string with the hash.
	 */
	public String getHash() {
		return hash;
	}

	/**
	 * Returns the nounce stored in the command.
	 * 
	 * @return a string with the nounce.
	 */
	public String getNounce() {
		return nounce;
	}

	/**
	 * Returns a string of the command. The string is compatible with the
	 * Johansson-Hallberg protocol.
	 * 
	 * @return a string of the command.
	 */
	@Override
	public String toString() {
		return ssn + ";" + hash + ";" + type + ";" + data + ";" + timestamp
				+ ";" + nounce;
	}

	/**
	 * Returns a string of the command. The string is used for logging.
	 * 
	 * @return a string of the command.
	 */
	public String logString() {
		return type + ": " + data;
	}

	/**
	 * Returns a string with the data in the command.
	 * 
	 * @return a string with the data.
	 */
	public String getData() {
		return data;
	}

	/**
	 * Returns a string with the timestamp in the command.
	 * 
	 * @return a string with the timestamp.
	 */
	public long getTimeStamp() {
		return timestamp;
	}

}
